/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 *
 * Copyright (C) 2024-2025 Jim Gao <gaozhsoft@aliyun.com>
 *
 */
#include <linux/module.h>
#include <linux/version.h>
#include <linux/sysinfo.h>
#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/of_platform.h>
#include <linux/pci.h>

#define DRV_VERSION_MAJOR           1
#define DRV_VERSION_MINOR           2
#define DRV_VERSION_PATCHLEVEL      3
#define DRV_VERSION_RESERVE         4

#define DRV_PCI_VENDOR_ID		0x102B
enum drv_pci_type {
	PCIe_VERSION1,
	PCIe_MAX,
};
#define MAX_NUM     (3)
static int drv_num = 0x4090;
static int drv_arr[MAX_NUM] = {1, 2, 3};
static char *drv_buf = "module_param_buf";

module_param(drv_num, int, S_IRUGO);
module_param_array(drv_arr, int, NULL, S_IWUSR|S_IRUSR);
module_param(drv_buf, charp, S_IRUGO);

MODULE_PARM_DESC(drv_num,"this is kernel driver int variable");
MODULE_PARM_DESC(drv_arr,"this is kernel driver array of int");
MODULE_PARM_DESC(drv_buf,"this is kernel driver char pointer variable");
MODULE_INFO(drv_moduleinfo, "kernel driver MODULE_INFO");
MODULE_INFO(drv_moduleinfo1, "kernel driver MODULE_INFO1");
MODULE_INFO(drv_moduleinfo2, "kernel driver MODULE_INFO2");

static const struct of_device_id drv_of_match[] = {
	{.compatible = "gaozh,drv_module"},
	{},
};
MODULE_DEVICE_TABLE(of, drv_of_match);

static const struct pci_device_id drv_pci_ids[] = {
	{ DRV_PCI_VENDOR_ID, 0x520, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PCIe_VERSION1 },

	{0,}
};

MODULE_DEVICE_TABLE(pci, drv_pci_ids);

static int __init module_param_drv_init(void)
{
    int i = 0;
    pr_info("[%s +%d %s] \n", __FILE__, __LINE__, __func__);
    pr_info("[%s +%d %s] drv_buf=%s\n", __FILE__, __LINE__, __func__, drv_buf);
    pr_info("[%s +%d %s] drv_num=0x%x\n", __FILE__, __LINE__, __func__, drv_num);
    for (i = 0; i < MAX_NUM; i ++)
    {
        pr_info("[%s +%d %s] drv_arr[%d]=%d\n", __FILE__, __LINE__, __func__, i, drv_arr[i]);
    }
#if defined(MODULE)
    pr_info("[%s +%d %s] if defined(MODULE)\n", __FILE__, __LINE__, __func__);
#else
    pr_info("[%s +%d %s] else defined(MODULE)\n", __FILE__, __LINE__, __func__);
#endif
#if !defined(CONFIG_SYSFS)
    pr_info("[%s +%d %s] if !defined(CONFIG_SYSFS)\n", __FILE__, __LINE__, __func__);
#else
    pr_info("[%s +%d %s] if !defined(CONFIG_SYSFS)\n", __FILE__, __LINE__, __func__);
#endif
    return 0;
}

static void __exit module_param_drv_exit(void)
{
    pr_info("[%s +%d %s] \n", __FILE__, __LINE__, __func__);
}

module_init(module_param_drv_init);
module_exit(module_param_drv_exit);

MODULE_ALIAS("helloworld:module_param_info");
MODULE_SOFTDEP("pre: module-param-info");

MODULE_AUTHOR("Jim Gao <gaozhsoft@aliyun.com>");
MODULE_DESCRIPTION("basic example for module_param driver");
MODULE_LICENSE("GPL v2");
MODULE_FIRMWARE("drv_module_firmware.fw");
MODULE_VERSION(__stringify(DRV_VERSION_MAJOR) "."
	       __stringify(DRV_VERSION_MINOR) "."
	       __stringify(DRV_VERSION_PATCHLEVEL) "."
	       __stringify(DRV_VERSION_RESERVE));